﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using My.Common.AutoMapper;
using Sale.DTO.Merchandise;

namespace Sale.DataAccess.Repository
{
    public class MerchandiseRepository : BaseRepository
    {
        public IEnumerable<MerchandiseDTO> GetMerchandiseList()
        {
            return Context.Merchandises.AsEnumerable()
                .Select(e => ObjectMapper.MapSourceToDestination<Merchandise, MerchandiseDTO>(e));
        }

        public void AddNew(MerchandiseDTO dto)
        {
            var entity = ObjectMapper.MapSourceToDestination<MerchandiseDTO, Merchandise>(dto);
            Context.Merchandises.InsertOnSubmit(entity);
        }

        public void Update(int id, MerchandiseDTO newDto)
        {
            var entity = GetMerchandiseEntityById(id);
            entity.MerchandiseName = newDto.MerchandiseName;
            entity.Madein = newDto.Madein;
            entity.Unit = newDto.Unit;
            entity.TradeMark = newDto.TradeMark;
            SubmitChanges();
        }

        public void Delete(int id)
        {
            var entity = GetMerchandiseEntityById(id);
            Context.Merchandises.DeleteOnSubmit(entity);
        }

        private Merchandise GetMerchandiseEntityById(int id)
        {
            return Context.Merchandises.SingleOrDefault(e => e.Id == id);
        }

        public QuantityInStockDTO GetQuantityInStock(int merchandiseId, DateTime from)
        {
            var mis = Context.MerchandiseInStocks.Where(e => e.MerchandiseId == merchandiseId && e.Date <= from)
                .OrderByDescending(e => e.Date)
                .FirstOrDefault();

            var result = new QuantityInStockDTO();
            if (mis != null)
            {
                result = ConvertQuantityFrom(mis);
            }
            return result;
        }

        private QuantityInStockDTO ConvertQuantityFrom(MerchandiseInStock entity)
        {
            return new QuantityInStockDTO()
            {
                FromDate = entity.Date,
                Quantity = entity.QuantityInStock,
                AverageUnitPrice = entity.AverageUnitPrice
            };
        }

        public bool CheckMerchandiseExistsInStock(int merchandiseId, DateTime from)
        {
            return Context.MerchandiseInStocks.Any(e => e.MerchandiseId == merchandiseId && e.Date.Date == from.Date);
        }


        private void UpdateQuantityInStock(int merchandiseId, DateTime from, double quantity, decimal? price = null)
        {
            var entity = Context.MerchandiseInStocks.SingleOrDefault(
                e => e.Date.Date == from.Date
                && e.MerchandiseId == merchandiseId);
            if (entity == null)
            {
                return;
            }
            entity.QuantityInStock = quantity;
            if (price.HasValue)
                entity.AverageUnitPrice = price.Value;
        }

        private void AddMerchandiseInStockItem(DateTime from, int merchandiseId, double quantity, decimal? price = null)
        {
            var entity = new MerchandiseInStock()
            {
                Id = Guid.NewGuid(),
                Date = from,
                MerchandiseId = merchandiseId,
                QuantityInStock = quantity,
                AverageUnitPrice = price.HasValue ? price.Value : 0,
            };
            Context.MerchandiseInStocks.InsertOnSubmit(entity);
        }

        public void RecordQuantityInStock(int merchandiseId, DateTime from, double quantity, decimal? price = null)
        {
            if (!CheckMerchandiseExistsInStock(merchandiseId, from))
            {
                AddMerchandiseInStockItem(from, merchandiseId, quantity, price);
            }
            else
            {
                UpdateQuantityInStock(merchandiseId, from, quantity, price);
            }
        }

        public void DeleteRecordQuantityInStock(int merchandiseId, DateTime from)
        {
            var entity = Context.MerchandiseInStocks.SingleOrDefault(e => e.MerchandiseId == merchandiseId && e.Date.Date == from.Date);
            Context.MerchandiseInStocks.DeleteOnSubmit(entity);
        }

        public MerchandiseDTO GetMerchandiseById(int id)
        {
            var entity = GetMerchandiseEntityById(id);
            return ObjectMapper.MapSourceToDestination<Merchandise, MerchandiseDTO>(entity);
        }

        //public IEnumerable<DateTime> GetAverageImportUnitPriceTimeList(DateTime from, int merchandiseId)
        //{
        //    var list = Context.AverageImportUnitPrices.Where(
        //        e => e.FromDate.Date >= from.Date
        //        && e.MerchandiseId == merchandiseId);
        //    return list.Select(e => e.FromDate)
        //        .AsEnumerable();

        //}
    }
}
